package com.agri.service.impl;

import com.agri.constant.FinancingConstant;
import com.agri.dto.FinancingApplyDTO;
import com.agri.dto.FinancingAuditDTO;
import com.agri.entity.FinancingOrder;
import com.agri.exception.FinancingException;
import com.agri.mapper.FinancingMapper;
import com.agri.result.Result;
import com.agri.service.FinancingService;
import com.agri.utils.EncryptUtil;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 融资服务实现类
 * 处理融资申请、审批、状态管理等业务逻辑
 *
 * @author Agri-Fin-Sale Team
 * @version 1.0
 * @since 2025-10-30
 */
@Service
@Transactional
public class FinancingServiceImpl implements FinancingService {
    private static final Logger log = LoggerFactory.getLogger(FinancingServiceImpl.class);

    @Autowired
    private FinancingMapper financingMapper;

    /**
     * 处理融资申请业务
     * 接收融资申请DTO，创建融资订单，加密敏感信息，保存到数据库
     *
     * @param dto 融资申请数据传输对象，包含用户信息和贷款详情
     * @return Result<?> 包含订单编号的成功结果或错误信息
     * @throws RuntimeException 当处理过程中发生异常时抛出
     */
    @Override
    public Result<?> apply(FinancingApplyDTO dto) {

        try {
            log.info("开始处理融资申请，请求参数: {}", dto);

            // 创建融资订单
            FinancingOrder order = new FinancingOrder();
            order.setRealName(dto.getRealName());
            order.setProductId(dto.getProductId()); // 设置融资产品ID

            // 加密敏感信息
            String encryptedIdCard = EncryptUtil.encrypt(dto.getIdCard());
            String encryptedPhone = EncryptUtil.encrypt(dto.getPhone());
            log.debug("加密后的身份证号: {}, 手机号: {}",
                EncryptUtil.maskIdCard(encryptedIdCard),
                EncryptUtil.maskPhone(encryptedPhone));

            order.setIdCard(encryptedIdCard);
            order.setPhone(encryptedPhone);
            order.setLoanAmount(dto.getLoanAmount());
            order.setCropType(dto.getCropType());
            order.setLoanPurpose(dto.getLoanPurpose());
            order.setIdCardFrontImg(dto.getIdCardFrontImg());
            order.setIdCardBackImg(dto.getIdCardBackImg());
            order.setStatus(FinancingConstant.STATUS_PENDING);
            order.setCreateTime(new Date());
            order.setUpdateTime(new Date());

            // 生成订单编号
            String orderNo = "AP" + System.currentTimeMillis() + (int)((Math.random()*9+1)*100000);
            order.setOrderNo(orderNo);
            log.info("生成的订单编号: {}", orderNo);

            // 插入数据库
            int result = financingMapper.insert(order);
            log.info("数据库插入结果: {} 条记录受影响", result);

            return Result.success(orderNo);
        } catch (Exception e) {
            log.error("处理融资申请时发生异常: ", e);
            throw new RuntimeException("处理融资申请失败: " + e.getMessage(), e);
        }
    }

    /**
     * 获取融资进度信息
     * 根据订单编号查询融资订单，返回脱敏后的订单详情
     *
     * @param orderNo 订单编号
     * @return Result<?> 包含脱敏后订单信息的成功结果或错误信息
     */
    @Override
    public Result<?> getProgress(String orderNo) {
        log.info("查询融资进度，订单编号：{}", orderNo);
        FinancingOrder order = financingMapper.selectByOrderNo(orderNo);
        if (order == null) {
            log.warn("融资订单不存在，订单编号：{}", orderNo);
            return Result.fail("融资订单不存在");
        }

        // 返回脱敏后的订单信息
        order.setIdCard(EncryptUtil.maskIdCard(order.getIdCard()));
        order.setPhone(EncryptUtil.maskPhone(order.getPhone()));
        log.info("融资进度查询成功，订单编号：{}", orderNo);
        return Result.success(order);
    }

    /**
     * 审批融资申请
     * 审核融资订单，更新审批状态和意见
     *
     * @param orderNo 订单编号
     * @param dto 审批数据传输对象，包含审批结果和意见
     * @return Result<?> 审批成功结果或错误信息
     * @throws FinancingException 当审批不满足条件时抛出
     */
    @Override
    public Result<?> audit(String orderNo, FinancingAuditDTO dto) {
        log.info("开始审批融资申请，订单编号：{}，审批参数：{}", orderNo, dto);
        FinancingOrder order = financingMapper.selectByOrderNo(orderNo);
        if (order == null) {
            log.warn("审批失败：融资订单不存在，订单编号：{}", orderNo);
            return Result.fail("融资订单不存在");
        }

        if (!FinancingConstant.STATUS_PENDING.equals(order.getStatus())) {
            log.warn("审批失败：当前状态{}不允许审批，订单编号：{}", order.getStatus(), orderNo);
            return Result.fail("当前状态不允许审批");
        }

        // 更新审批状态
        order.setStatus(dto.getApproved() ? FinancingConstant.STATUS_APPROVED : FinancingConstant.STATUS_REJECTED);
        order.setAuditOpinion(dto.getAuditOpinion());
        order.setAuditorId(dto.getAuditorId());
        order.setAuditTime(new Date());
        order.setUpdateTime(new Date());

        financingMapper.updateById(order);
        log.info("融资申请审批完成，订单编号：{}，审批结果：{}", orderNo, order.getStatus());
        return Result.success();
    }

    /**
     * 更新融资订单状态
     * 根据订单编号和目标状态更新订单状态，验证状态流转合法性
     *
     * @param orderNo 订单编号
     * @param status 目标状态代码
     * @return Result<?> 成功结果或错误信息
     */
    @Override
    public Result<?> updateStatus(String orderNo, Integer status) {
        FinancingOrder order = financingMapper.selectByOrderNo(orderNo);
        if (order == null) {
            log.warn("更新状态失败：融资订单不存在，订单编号：{}", orderNo);
            return Result.fail("融资订单不存在");
        }

        // 验证状态流转是否合法
        if (!FinancingConstant.isValidStatusTransition(order.getStatus(), status)) {
            log.warn("状态变更不合法：从{}到{}", order.getStatus(), status);
            return Result.fail("状态变更不合法");
        }

        order.setStatus(status);
        order.setUpdateTime(new Date());
        financingMapper.updateById(order);
        log.info("订单状态更新成功：订单编号{}，新状态{}", orderNo, status);
        return Result.success();
    }

    /**
     * 查询融资订单列表
     * 根据状态筛选融资订单，返回订单列表
     *
     * @param status 订单状态代码（可选）
     * @return Result<?> 包含订单列表的成功结果
     */
    @Override
    public Result<?> list(Integer status) {
        log.info("查询融资订单列表，状态筛选：{}", status);
        List<FinancingOrder> orders = financingMapper.selectByStatus(status);

        // 解密敏感信息
        for (FinancingOrder order : orders) {
            try {
                if (order.getIdCard() != null) {
                    order.setIdCard(EncryptUtil.decrypt(order.getIdCard()));
                }
                if (order.getPhone() != null) {
                    order.setPhone(EncryptUtil.decrypt(order.getPhone()));
                }
            } catch (Exception e) {
                log.warn("解密敏感信息失败，订单编号：{}，错误：{}", order.getOrderNo(), e.getMessage());
                // 解密失败时保持原加密数据，避免影响其他功能
            }
        }

        return Result.success(orders);
    }
}